home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / wmv12s.zip / FSTAT.C < prev    next >
Text File  |  1993-01-04  |  5KB  |  176 lines

  1. /* find first matching file and find next matching file
  2. ** written by Peter Wu @ Faculty Support Center @ Univ. of Wisconsin
  3. ** July 1986
  4. **
  5. ** These functions have an extended capability to search for
  6. ** directories only and ffmf does not return "." and "..", also
  7. ** ffmf will attempt to find root directory and return at least drive number
  8. */
  9. #define LINT_ARGS
  10.  
  11. #include "dta.h"
  12. #include <dos.h>
  13. #include <stdlib.h>
  14.  
  15. char lastc(char *);
  16.  
  17. ffmf(fn,attr,dta)  /* extended version of ffmf1; fn must be normalized */
  18. char *fn;
  19. short attr;
  20. union dtbuf *dta;
  21. {
  22.   int status, len;
  23.   char tmpfn[200];
  24.   union dtbuf tmpdta;
  25.  
  26.   if (lastc(fn) != '\\') {  /* if not looking for root directory */
  27.  
  28.     status = ffmf1(fn,attr,dta);
  29.     if (status) {
  30.       return status;
  31.     }
  32.  
  33.     /* get rid of "." and ".." */
  34.     while (dta->dos.fn[0] == '.') {
  35.       status = fnmf1(dta);
  36.       if (status) {
  37.     return status;
  38.       }
  39.     }
  40.  
  41.     /* now check to see if we should return plain files or not */
  42.     while ( ((dta->dos.e_attr & A_FIL) == 0) &&
  43.         ((dta->dos.attr & A_DIR) == 0) ) {
  44.       /* user didn't ask for plain files and we found one, so skip it */
  45.       status = fnmf1(dta);
  46.       if (status) {
  47.     return status;
  48.       }
  49.     }
  50.  
  51.     fixdta(dta,dta);
  52.     return 0;
  53.   }
  54.  
  55.   /* fn ends with '\', i.e. looking for root directory. In DOS 3 ffmf1 won't
  56.   ** find root directory, and in DOS 2 ffmf1 found root directory but reports
  57.   ** it to have file status! Neither is right. So I have to fix it here.
  58.   ** The reason for wanting to look for a root directory is to find out
  59.   ** what drive it's on.
  60.   */
  61.  
  62.   if (attr & A_DIR) {
  63.     /* look for '\*.*' */
  64.     strcpy(tmpfn, fn);
  65.     strcat(tmpfn, "*.*");
  66.     status = ffmf1(tmpfn, A_DIR | A_FIL, &tmpdta);
  67.     if (status) {  /* can't even find root this way: root must be empty */
  68.       cputs("empty root directory; nothing to move\n\015");
  69.       exit(1);
  70.     }
  71.  
  72.     /* found root; now fill in dta */
  73.     dta->dos.fn[0] = '\0';
  74.     dta->dos.attr = A_DIR;
  75.     fixdta(&tmpdta,dta);
  76.     return 0;
  77.   } else {
  78.     return 1; /* can't find root because attr is not set to A_DIR */
  79.   }
  80. }
  81.  
  82. /* extended version of fnmf1; because of the way ffmf handle root directory,
  83. ** calling ffmf to find root directory and then call fnmf will cause an
  84. ** "allocation table bad" error
  85. */
  86. fnmf(dta)
  87. union dtbuf *dta;
  88. {
  89.   int status;
  90.  
  91.   status = fnmf1(dta);
  92.   if (status) {
  93.     return status;
  94.   }
  95.  
  96.   while (((dta->dos.e_attr & A_FIL) == 0) && ((dta->dos.attr & A_DIR) == 0)) {       /* user didn't ask for plain file and we found one, so skip it */
  97.     status = fnmf1(dta);
  98.     if (status) {
  99.       return status;
  100.     }
  101.   }
  102.  
  103.   fixdta(dta,dta);
  104.   return 0;  /* no error */
  105. }
  106.  
  107. /* copy dos dependent dta fields to the dos independent dta fields */
  108. fixdta(from, to)
  109. union dtbuf *from, *to;
  110. {
  111.   switch (_osmajor) {
  112.  
  113.     case 3:  /* dos 3.xx */
  114.       to->dos.drv_no = from->dos3.drv_no;
  115.       to->dos.slotl = from->dos3.slotl;
  116.       to->dos.sloth = from->dos3.sloth;
  117.       to->dos.clusl = from->dos3.clusl;
  118.       to->dos.clush = from->dos3.clush;
  119.  
  120.       to->dos3.drv_no = from->dos3.drv_no;  /* for compatiblity sake */
  121.       break;
  122.  
  123.     case 2:  /* dos 2.xx */
  124.       to->dos.drv_no = from->dos2.drv_no + 1;
  125.       to->dos.slotl = from->dos2.slotl;
  126.       to->dos.sloth = from->dos2.sloth;
  127.       to->dos.clusl = from->dos2.clusl;
  128.       to->dos.clush = from->dos2.clush;
  129.  
  130.       to->dos2.drv_no = from->dos2.drv_no;  /* for compatiblity sake */
  131.       break;
  132.  
  133.     default:
  134.       cputs("unexpected DOS version\n\015");
  135.       error("fixdta", 0);
  136.   }
  137. }
  138.  
  139. ffmf1(fn,attr,dta)  /* don't call this, call ffmf */
  140. char *fn;
  141. short attr;
  142. union dtbuf *dta;
  143. {
  144.   union REGS inregs,outregs;
  145.  
  146.   dta->dos.e_attr = attr;  /* store the extended attribute */
  147.   bdos(0x1a, (int) dta, 0);  /* set dta */
  148.  
  149.   inregs.h.ah = 0x4e;
  150.   inregs.x.dx = (int) fn;
  151.   inregs.x.cx = attr & 0x3f;  /* mask off the A_FIL bit */
  152.   intdos(&inregs, &outregs);  /* now find first entry */
  153.  
  154.   if (outregs.x.cflag) {
  155.     return outregs.x.ax;  /* return error code */
  156.   }
  157.   return 0;  /* no error */
  158. }
  159.  
  160. fnmf1(dta)  /* find next matching file */
  161. union dtbuf *dta;
  162. {
  163.   union REGS inregs,outregs;
  164.  
  165.   bdos(0x1a, (int) dta, 0);  /* set dta */
  166.  
  167.   inregs.h.ah = 0x4f;
  168.   intdos(&inregs, &outregs);  /* now find next entry */
  169.  
  170.   if (outregs.x.cflag) {
  171.     return (outregs.x.ax);
  172.   } else {
  173.     return (0);
  174.   };
  175. }
  176.